import { ApplicationRef, ComponentFactoryResolver, ComponentRef, Injectable, Injector } from '@angular/core';
import { Observable } from 'rxjs';
import { AuditComponent } from './audit/audit.component';

@Injectable({
  providedIn: 'root'
})
export class AuditService {
  constructor(
    private factory: ComponentFactoryResolver,
    private appRef: ApplicationRef,
    private injector: Injector
  ) { }
  /**
   * createAuditPopup 动态创建Audit组件并且弹出
   * @param options 审批框参数
   * @return observable 接收确认取消事件
   * @return destory 使用完毕后销毁组件
   * @example 
   * const {destroy, observable} = this.audit.createAuditPopup({title: '审核', auditText: '审批意见'});
   * observable.subscribe(res => {
   *     console.log('currRes', res);
   *     
   * })
   */
  createAuditPopup(options: {title?: string, auditText?: string} = {}): {
    observable: Observable<any>,
    destroy: () => void;
  }{
    const result: any = {};
    const instance = this.generate(AuditComponent);
    result.destroy = () => {this.destroy(instance)};
    if(options.title) {
      instance.instance.title = options.title;
    }
    if(options.auditText) {
      instance.instance.auditText = options.auditText;
    }

    instance.instance.show();
    result.observable = instance.instance.currState$.asObservable();
    return result;
  }
  generate(Container: any): ComponentRef<any> {
    const comp: ComponentRef<any> = this.factory.resolveComponentFactory(Container).create(this.injector);
    this.appRef.attachView(comp.hostView);

    const id = this.makeId();
    const hostElement: HTMLElement = document.createElement('div')
    hostElement.setAttribute('id', id)
    comp.instance.id = id
    hostElement.appendChild((<any>comp.hostView).rootNodes[0])
    document.body.appendChild(hostElement)

    return comp;
  }
  destroy(com: ComponentRef<any>): void {
    const timer = setTimeout(() => {
      this.destroyWait(com)
      clearTimeout(timer)
    }, 500)
  }

  destroyWait(com: ComponentRef<any>): void {
    const id = com.instance.id
    this.appRef.detachView(com.hostView)
    com.destroy()
    try {
      const hostElement = document.getElementById(id)
      hostElement && hostElement.parentElement.removeChild(hostElement)
    } catch (err) {}
  }

  makeId() {
    return Math.random().toString(16).substr(2, 8)
  }
}
